/*Download*/

#include "threadPool.h"

int getMD5(char* path, char* usename, MYSQL *db, unsigned char* md5);
int transFile(int netfd, char *md5, off_t offset);

int download(int netfd, char *path, off_t offset, char* usename, MYSQL *db)
{
    unsigned char md5[16] = {0};
    if(getMD5(path, usename, db, md5) != 0)
    {
       printf("no this file\n");
       return -1;
    }
    printf("download : md5 =%s\n", md5);
    transFile(netfd, md5, 0);
}

//在表中查找md5值
int getMD5(char* path, char* usename, MYSQL *db, unsigned char* md5)
{
    char sql[1024] = {0};

    sprintf(sql,"select md5 from vftable where username = '%s' and path = '%s' and fileType = '1' and tomb = '0';", usename, path);
    printf("sql = %s\n", sql);

    int qret = mysql_query(db, sql);
    if(qret != 0)
    {
        printf("SQL error:%s\n", mysql_error(db));
        return -1;
    }                                                                                                                                                       

    MYSQL_RES *table = mysql_store_result(db);
    if(mysql_num_rows(table) == 0)
    {
        return -1;
    }
    MYSQL_ROW row;
    while((row = mysql_fetch_row(table)) != NULL){
        for(unsigned int i = 0; i < mysql_num_fields(table); ++i){
            strcat(md5, row[i]); // 取出表里存的md5值
        }
    }
    printf("getMD5 : md5 =%s\n", md5);
    return 0;
}

// 发送文件
int transFile(int netfd, char *filename)
{
    train_t train;
    off_t offset;
    recv(netfd, &offset, sizeof(offset), 0);

    int fd = open(filename, O_RDWR);
    struct stat statbuf;
    // 获取文件大小
    fstat(fd, &statbuf);
    // 发送小火车 火车头 size的长度 火车车厢 size的内容
    bzero(&train, sizeof(train));
    off_t realSize = statbuf.st_size - offset;

    train.length = sizeof(realSize);
    memcpy(train.data, &realSize, train.length);
    send(netfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);

    if (realSize > 100 * 1024 * 1024)
    {
        // 如果文件大于100M，使用mmap
        lseek(fd, offset, SEEK_CUR);
        char *p = (char *)mmap(NULL, realSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        ERROR_CHECK(p, MAP_FAILED, "mmap");
        off_t totalsize = 0; // 记录已经发送的长度
        while (totalsize < realSize)
        {
            if (realSize - totalsize > (long)sizeof(train.data))
            {
                train.length = sizeof(train.data); // 剩余数据超过火车车厢的上限
            }
            else
            {
                train.length = realSize - totalsize;
            }
            send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
            send(netfd, p + totalsize, train.length, MSG_NOSIGNAL);
            totalsize += train.length;
        }
        munmap(p, realSize);
    }
    else
    {
        // 小于100M，普通发送
        lseek(fd, offset, SEEK_CUR);
        while (1)
        {
            // 将文件的数据读取到小火车的车厢部分          
            ssize_t sret = read(fd, train.data, sizeof(train.data));
            train.length = sret;
            // 发送小火车
            send(netfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
            if (sret == 0)
            {
                break;
            }
        }
    }

    // 补发一个空火车
    train.length = 0;
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    close(fd);

    return 0;
}
